/*********************************************************************************
 *      Copyright:  (C) 2022 YanlinZhou<1222>
 *                  All rights reserved.
 *
 *       Filename:  getopt.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/09/2022)
 *         Author:  YanlinZhou <1222>
 *      ChangeLog:  1, Release initial version on "04/09/2022 08:32:13 AM"
 *                 
 ********************************************************************************/

#include "main.h"
#include "log.h" 
#define DEBUG 0

struct option opts[] =
{
	{ "ipaddr", required_argument, NULL, 'i' },
    { "port",   required_argument, NULL, 'p' },
    { "deamon", no_argument, NULL, 'd' },
    { "help",   no_argument, NULL, 'h' },
    {0, 0, 0, 0}
};

int main (int argc, char **argv)
{
	int 			rv = -1;
	int				i = 0;
	int             ch;
	int            	idx;
	int 			listen_port = 0;
	int				my_daemon = 0;
	int				listen_fd  = -1;
	struct 			epoll_event ev, events[MAX_EVENTS];
	int  			conn_fd, nfds, epollfd;
	char			buf[64];
	sqlite3			*db = NULL;
	char			*time = NULL;
	char			*name = NULL;
	char			*temp = NULL;

	while( (ch=getopt_long(argc, argv, "p:hd",opts,&idx)) != -1 )
	{
		switch(ch)
		{
			case 'd':
				my_daemon = 1;
				break;
			case 'p':
				listen_port=atoi(optarg);
				break;
			case 'h':
				print_server_usage(basename(argv[0]));
				return 0;
		}

	}


	if(!listen_port)
	{
		print_server_usage(basename(argv[0]));
		return -1;
	}


   /* open mylog */
    if(DEBUG) //set set log to standard output for debug
    {   
        if( logger_init("stdout", LOG_LEVEL_DEBUG) < 0 ) 
        {
            log_error("initial logger system failure\n");
            return -1; 
        }

        log_info("ste program running on debug now!\n");
    }   
    else //set log to logfile 
    {   
        if(logger_init("stdout", LOG_LEVEL_INFO) < 0)
        {
            log_error("initial logger system failure\n");
            return -2; 
        }

        log_info("The system logs are recorded!\n");
    }   


	if( (listen_fd = socket_server_init(NULL, listen_port)) < 0 )
	{
		log_error("call socket_server_init function failure :%s\n", strerror(errno));
		return -1;
	}
	log_debug("create listen_fd sucessfully and listenning on port[%d]\n", listen_port);

	if( (rv = create_database(&db)) < 0)
	{
		log_error ("create_database failure:%s\n", strerror(errno));
		return -2;
	}
	log_debug("create_database sucessfully!\n");

	if( (rv = create_table(db)) < 0)
	{
		log_error ("create_table failure:%s\n", strerror(errno));
		return -2;
	}
	log_debug("create_table sucessfully!\n");

	if(my_daemon)
	{
		log_error ("Is going to run at daemon......\n");
		if( daemon(0,0) < 0 )
		{
			log_error ("daemon failure:%s\n",strerror(errno));
			return -1;
		}
	}

	epollfd = epoll_create(MAX_EVENTS);
	if (epollfd == -1) 
	{
   		 log_error("epoll_create failure:%s\n", strerror(errno));
   		 exit(EXIT_FAILURE);
     }

    ev.events = EPOLLIN;
    ev.data.fd = listen_fd;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) 
	{
        log_error("epoll_ctl failure:%s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

	log_info("waiting events to happen!\n");

	while (1) 
	{
		log_debug("waiting events to happen!\n");
		nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
		if (nfds == -1) 
		{
			log_error("epoll_wait failure : %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
	
		for (i = 0; i < nfds; i++)
		{
			if (events[i].data.fd == listen_fd) /* new client to connect */
			{
				conn_fd = accept(listen_fd,(struct sockaddr *) NULL, NULL);
				if (conn_fd == -1) 
				{
					log_error("accept failure :%s\n", strerror(errno));
					exit(EXIT_FAILURE);
				}
				ev.events = EPOLLIN | EPOLLET;
				ev.data.fd = conn_fd;
				if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_fd,&ev) == -1)
				 {
					log_error("epoll_ctl failure:%s\n", strerror(errno));
					exit(EXIT_FAILURE);
				}
			} 
			
			else /* already connect client has events */
			{
				memset(buf, 0, sizeof(buf));
				if( (rv = read(events[i].data.fd, buf, sizeof(buf))) <= 0 )
					{
						log_error("Read failure or client disconnected!\n");
						epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
						close(events[i].data.fd);
						continue;
					}
					printf("Receive[%d] Bytes from [%d]:%s\n", rv, events[i].data.fd, buf);

					name = strtok(buf, "/");
					log_debug("name = %s\n",name);
					temp = strtok(NULL, "/");
					log_debug ("name = %s\n",temp);
					time = strtok(NULL, "/");
					log_debug("name = %s\n",time);

					if( (rv = server_save_data(name, temp, time, db)) <0 )
					{
						log_error ("server_save_data function call failure:%s\n", strerror(errno));
						continue;
					}
					printf("server_save_data sucessfully!\n");
					log_debug("server_save_data sucessfully\n");
			}
		}
	}

	return 0;
} 


